package com.example.games.core;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

public abstract class GameView extends SurfaceView implements
		SurfaceHolder.Callback, Runnable, OnGestureListener, OnTouchListener {

	public Canvas mCanvas;

	private Thread mThread;

	private SurfaceHolder mSurfaceHolder;
	private boolean mIsRunning = false;
	private int TIME_IN_FRAME = 50;// 1帧=50ms
	GestureDetector gd;

	public GameView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		init();
	}

	public GameView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init();
	}

	public GameView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init();
	}

	public Paint paint;

	private void init() {
		GameHelper.printLog("GameView init");
		mSurfaceHolder = getHolder();
		mSurfaceHolder.addCallback(this);

		gd = new GestureDetector(this);
		this.setOnTouchListener(this);
		this.setLongClickable(true);
		this.setKeepScreenOn(true);
		this.setFocusableInTouchMode(true);

		paint = new Paint();
		paint.setAntiAlias(true);

		loadResource();
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
		// TODO Auto-generated method stub
		GameHelper.printLog("GameView surfaceChanged");
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		GameHelper.printLog("GameView surfaceCreated");
		mIsRunning = true;

		mThread = new Thread(this);
		mThread.start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		GameHelper.printLog("GameView surfaceDestroyed");
		mIsRunning = false;
		if (mThread.isAlive()) {
			mThread.interrupt();
		}
	}

	@Override
	public void run() {
		while (mIsRunning) {
			long startTime = System.currentTimeMillis();

			try {
				synchronized (mSurfaceHolder) {
					mCanvas = mSurfaceHolder.lockCanvas();
					mCanvas.drawColor(Color.WHITE);// 刷屏
					mCanvas.setDrawFilter(new PaintFlagsDrawFilter(0,
							Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
					gameDraw();
					gameLogic();

					long endTime = System.currentTimeMillis();
					int consumeTime = (int) (endTime - startTime);
					frameControl(consumeTime);

				}
			} catch (Exception e) {
				//
			} finally {
				if (mCanvas != null) {
					mSurfaceHolder.unlockCanvasAndPost(mCanvas);
				}

			}

		}

	}

	/**
	 * 资源加载
	 */
	public abstract void loadResource();

	/**
	 * 游戏绘制
	 */
	public abstract void gameDraw();

	/**
	 * 游戏逻辑
	 */
	public abstract void gameLogic();

	public void pauseDraw() {
		mIsRunning = false;
	};

	public void resumeDraw() {
		mIsRunning = true;
	};

	/**
	 * 帧控制
	 * 
	 * @param consumeTime
	 */
	private void frameControl(int consumeTime) {
		long waitTime = 0;
		try {
			waitTime = TIME_IN_FRAME - consumeTime;
			if (waitTime > 0) {
				Thread.sleep(waitTime);
			} else {
				waitTime = 0;
			}
		} catch (InterruptedException e) {
			// ignore
			GameHelper.printLog(e.getMessage());
		}
		float fps = 1000.0f / (consumeTime + waitTime);

		if (null != mCanvas && GameHelper.isDrawFPS()) {
			// 绘制FPS
			paint.reset();
			paint.setColor(Color.RED);
			paint.setTextSize(20);
			mCanvas.drawText("FPS:" + String.valueOf(fps), 80, 50, paint);
		}
	}

	@Override
	public boolean onDown(MotionEvent e) {
		GameHelper.printLog("onDown");
		return true;
	}

	/**
	 * 用户的轻拂手势，Touch了滑动一点距离后，up时触发。
	 */
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		GameHelper.printLog("onFling");
		return false;
	}

	/**
	 * 用户按下并保持一段时间后调用（Touch了不移动一直Touch down时触发）
	 */
	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
		GameHelper.printLog("onLongPress");

	}

	/**
	 * Touch了滑动时触发。
	 */
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		// TODO Auto-generated method stub
		GameHelper.printLog("onScroll");
		return true;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
		GameHelper.printLog("onShowPress");

	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		GameHelper.printLog("onSingleTapUp");
		return true;
	}

	@Override
	public boolean onTouch(View arg0, MotionEvent arg1) {
		// TODO Auto-generated method stub
		return gd.onTouchEvent(arg1);
	}

}
